package com.sky.server;

import com.sky.utils.RedisHashUtils;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import jakarta.annotation.Resource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.net.InetAddress;

/**
 * netty服务器启动配置
 * @author Administrator
 */
@Component
public class WebSocketServer {

    @Resource
    private WebSocketChannelInitializer webSocketChannelInitializer;

    @Value("${websocket.port}")
    private Integer websocketPort;

    public void start(){
        //创建两个线程组，bossGroup处理线程的注册，workGroup处理具体事务的执行
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        try {
            //设置服务器启动类启动参数
            ServerBootstrap bootstrap = new ServerBootstrap();

            bootstrap.group(bossGroup,workerGroup)
                    //设置服务端通道实现类型
                    .channel(NioServerSocketChannel.class)
                    //设置线程队列的连接个数
                    .option(ChannelOption.SO_BACKLOG,128)
                    //设置保持活动连接状态
                    .childOption(ChannelOption.TCP_NODELAY,true)
                    //使用匿名内部类的方式初始化channel通道对象
                    .childHandler(webSocketChannelInitializer);

            //绑定端口号，启动服务
            ChannelFuture channelFuture = bootstrap.bind(websocketPort).sync();

            // 服务器上线
            String serverUrl = InetAddress.getLocalHost().getHostAddress() + ":" + websocketPort;
            System.out.println("服务器---->" + serverUrl + "启动成功!");

            //对关闭通道进行监听
            channelFuture.channel().closeFuture().sync();

            // 返回与当前Java应用程序关联的运行时对象
            Runtime.getRuntime().addShutdownHook(new Thread(() -> {
                bossGroup.shutdownGracefully();
                workerGroup.shutdownGracefully();
            }));
        } catch (Exception e) {
            System.out.println("************netty server 出现异常*************");
            e.printStackTrace();
        }
    }

    /** 项目停止时清除netty服务器相关redis缓存 **/
    public void destroy() throws Exception{
        String serverUrl = InetAddress.getLocalHost().getHostAddress() + ":" + websocketPort;
        RedisHashUtils.clearNettyCache(serverUrl);
    }
}
